import json
import os
import uuid
from oss2 import Auth, Bucket
import subprocess
from flask import request
from base import base # 绝对导入 base 蓝图和模型
from flask import jsonify,Response,stream_with_context
from models import PptTemplate
from utils.dify.client import (
    ChatClient,
    CompletionClient,
    DifyClient,
    KnowledgeBaseClient,
    WorkflowClient
)
from utils.ollama import OllamaClient

CHAT_API_KEY = os.environ.get("DIFY_API_KEY","app-kCz6EOsO6aQWK4LPBbtUt4xoc")
FLOW_API_KEY = os.environ.get("FLOW_API_KEY","app-0frngaC9UobsOZNn4SoRSSxWu")
API_BASE_URL = os.environ.get("DIFY_API_BASE_URL", "https://api.dify.ai/v1")

@base.route('/ai/chat/blocking', methods=['POST'])
def ai_chat_blocking():
    chat_client = ChatClient(CHAT_API_KEY, base_url=API_BASE_URL)
    chat_response = chat_client.create_chat_message(inputs={}, query="你好", user="123",
                                                response_mode="blocking")
    chat_response.raise_for_status()

    result = chat_response.json()

    print(result.get("answer"))
    return jsonify(result)



@base.route('/ai/chat/streaming', methods=['POST'])
def ai_chat_streaming():
    chat_client = ChatClient(CHAT_API_KEY, base_url=API_BASE_URL)

    # 获取请求的JSON数据
    json_data = request.get_json()

    # 定义一个生成器函数，用于实时发送数据
    def generate():
        try:
            # 创建聊天消息，这里假设你已经处理了接收到的数据
            chat_response = chat_client.create_chat_message(inputs=json_data, query="给我讲个故事吧", user="123",
                                                            response_mode="streaming")

            # 检查请求是否成功
            if chat_response.status_code != 200:
                yield "data: Failed to retrieve data\n\n"
                return

            # 逐块读取聊天客户端返回的数据并返回给客户端
            for chunk in chat_response.iter_content(chunk_size=1024):
                if chunk:  # 如果读取到有效数据
                    yield chunk.decode('utf-8')
        except Exception as e:
            yield f"data: Error: {str(e)}\n\n"

    # 使用 Flask 的 Response 对象逐块返回数据
    return Response(stream_with_context(generate()), content_type='text/event-stream')


@base.route('/ai/chat/generate_ppt', methods=['GET'])
def ai_chat_generate_ppt():
    # 判断参数是否存在
    template_id=request.args.get('template_id')
    user_input=request.args.get('user_input')
    if not template_id:
        return jsonify({'msg': '模板ID为必填', 'code': 400}), 400
    if not user_input:
        return jsonify({'msg': '用户输入为必填', 'code': 400}), 400
    ppt_template=PptTemplate().query.filter_by(id=template_id).first();
    if not ppt_template:
        return jsonify({'msg': '没有找到这个模板', 'code': 400}), 400
    try:
        # 请求大模型生成PPT
        workflow_client=WorkflowClient(FLOW_API_KEY, base_url=API_BASE_URL)
        workflow_response=workflow_client.run(inputs={"user_input":user_input}, user="123", response_mode="blocking")
        workflow_response.raise_for_status()
        result = workflow_response.json()
        text_output = None
        if 'data' in result and 'outputs' in result['data'] and 'text' in result['data']['outputs']:
            text_output = result['data']['outputs']['text']
            try:
                text_output = json.loads(text_output)  # 将字符串转换为JSON对象
            except json.JSONDecodeError as e:
                return jsonify({'msg': 'JSON解析错误', 'code': 500, 'error': str(e)}), 500
        # 将ppt模板内容中的变量替换为生成的文本
        template_content = ppt_template.template_content
        if text_output:
            template_content = template_content.replace('{{title}}', text_output.get('title', ''))
            template_content = template_content.replace('{{menuList}}', text_output.get('menuList', ''))
            template_content = template_content.replace('{{contents}}', text_output.get('contents', ''))
        
        # 将template_content写入到一个临时的Markdown文件
        markdown_file = 'temp.md'
        with open(markdown_file, 'w') as f:
            f.write(template_content)

        # 使用marp将Markdown文件转换为PPT
        ppt_file = 'output.pptx'
        subprocess.run(['marp', markdown_file, '-o', ppt_file], check=True)

        # 上传PPT到OSS
        bucket_name="superlu-demo"
        endpoint="oss-cn-beijing.aliyuncs.com"
        auth = Auth('LTAI5tDocP7xZz5qh53hRzxHN', 'uf1FPv7s6ioHonorhpdmr9T7FxXoxg7')
        bucket = Bucket(auth, endpoint, bucket_name)
        oss_path = f'path/to/{uuid.uuid4()}.pptx'
        oss_base_path=f"https://{bucket_name}.{endpoint}/"
        bucket.put_object_from_file(oss_path, ppt_file)

        # 删除临时文件
        os.remove(markdown_file)
        os.remove(ppt_file)

        return jsonify({'msg': 'ok', 'code': 200, 'data':{'content': template_content,'ppt_url':oss_base_path+oss_path}}), 200
    except Exception as e:
        return jsonify({'msg': str(e), 'code': 500}), 500



@base.route('/ai/ollama', methods=['POST'])
def test_ollama():
    system_prompt="""# 角色
你是一个高效的 PPT 生成助手，能够根据用户输入的标题内容，以简洁明了的方式生成 PPT，并以 JSON 格式返回。擅长使用 Marp 语法呈现 PPT 内容，使目录以 Marp 列表形式展现。

## 技能
### 技能 1：生成 PPT
1. 当用户提供标题时，根据标题内容生成 PPT 的目录内容，以 Marp 列表形式呈现。
2. 将 PPT 内容以 Marp 语法进行组织，每一页之间用“---”隔开。
3. 要求每张内容除标题外要包含内容及重点
===回复示例===
{
"title":"<首页标题>",
"menuList":"- 目录项 1\n- 目录项 2",
"contents":"第一页内容\n---\n第二页内容"
}
===示例结束===

## 限制:
- 仅根据用户提供的标题生成 PPT，不涉及其他无关主题。
- 严格按照给定的 JSON 格式和 Marp 语法进行输出。"""
    ollama_client=OllamaClient()
    response =ollama_client.create_chat_message(model='glm4:9b',system_prompt=system_prompt, user_input='计算机与科学技术')
    
    return jsonify({'msg': 'ok', 'code': 200, 'data':response.message.content})
